package com.compose.universally.okhttp

import com.compose.universally.utils.log
import com.compose.universally.utils.showInfoToast
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okhttp3.internal.ws.RealWebSocket
import okio.ByteString
import java.util.concurrent.TimeUnit


open class OKWebSocketListener : WebSocketListener() {

    open fun onStatus(isConnect: Boolean) {

    }
}


class OKHttpWebSocket(
    private val url: String,
    private val listener: OKWebSocketListener,
    private val resetConnect: Boolean = true
) {

    private val client = OkHttpClient.Builder().addInterceptor(OKHttpLogInterceptor())
        .readTimeout(30, TimeUnit.SECONDS)// 设置读取超时时间
        .writeTimeout(30, TimeUnit.SECONDS)// 设置写的超时时间
        .connectTimeout(30, TimeUnit.SECONDS)// 设置连接超时时间
        .retryOnConnectionFailure(true)// 断线重连
        .pingInterval(2, TimeUnit.SECONDS).build()

    private var webSocket: RealWebSocket?

    private var webSocketListener = object : OKWebSocketListener() {

        override fun onStatus(isConnect: Boolean) {
            super.onStatus(isConnect)
            listener.onStatus(isConnect)
        }

        override fun onOpen(webSocket: WebSocket, response: Response) {
            super.onOpen(webSocket, response)
            listener.onOpen(webSocket, response)
            onStatus(true)
            showInfoToast("WebSocket连接成功")
            log("Personal WebSocket onOpen:${response}")
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            super.onMessage(webSocket, text)
            listener.onMessage(webSocket, text)
        }

        override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
            super.onMessage(webSocket, bytes)
            listener.onMessage(webSocket, bytes)
        }

        override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosed(webSocket, code, reason)
            listener.onClosed(webSocket, code, reason)
            onStatus(false)
            showInfoToast("WebSocket关闭")
            if (resetConnect) {
                resetConnect()
            }
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            super.onFailure(webSocket, t, response)
            listener.onFailure(webSocket, t, response)
            onStatus(false)
            showInfoToast("WebSocket连接失败")
            log("Personal WebSocket onFailure:${t.message} response:${response}")
            if (resetConnect) {
                resetConnect()
            }
        }
    }

    init {
        webSocket = client.newWebSocket(
            Request.Builder().url(url).build(), webSocketListener
        ) as RealWebSocket
    }

    // 发送
    fun send(message: String): Boolean {
        return webSocket?.send(message) ?: false
    }

    // 重连
    fun resetConnect() {
        close()
        val request: Request = Request.Builder().url(url).build()
        webSocket = client.newWebSocket(request, webSocketListener) as RealWebSocket
    }


    // 断开
    fun close() {
        webSocket?.cancel()
        webSocket = null
    }

}